home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / dev / gui / textfield.lha / Textfield / SafeGIRPort / SafeGIRPort.a < prev    next >
Text File  |  1995-01-31  |  4KB  |  199 lines

  1. ; SafeGIRPort
  2. ; Patches ObtainGIRPort() to fix MagicMenu
  3. ; and CycleToMenu problem
  4. ;
  5. ; Based heavily on NewObtainGIRPort, but with
  6. ; fixes.  Specifically, the caches weren't
  7. ; being cleared on removal.  Plus, some speed
  8. ; improvements in the patch code.  Hopefully
  9. ; it narrows the gap for someone locking the
  10. ; layer between the patch's unlock and original
  11. ; call.
  12.  
  13.     INCLUDE    'intuition/cghooks.i'
  14.  
  15. ObtainGIRPort    EQU    -$22E
  16. DisplayBeep        EQU    -$60
  17.  
  18. OpenLibrary        EQU    -$228
  19. CloseLibrary    EQU    -$19E
  20. SetFunction        EQU    -$1A4
  21. Forbid            EQU    -$84
  22. Permit            EQU    -$8A
  23. Wait            EQU    -$13E
  24. CacheClearU        EQU    -$27c
  25.  
  26. Delay            EQU -$C6
  27. PutStr            EQU    -$3B4
  28.  
  29. AttemptLockLayerRom    EQU    -$28E
  30. UnlockLayerRom    EQU    -$1B6
  31.     
  32. SIGBREAKF_CTRL_C    EQU 1<<12
  33.     
  34.     section text,code
  35.     
  36. _PatchOGR:
  37.     moveq    #20,d7
  38.  
  39.     ; Open libraries    
  40.     lea        gfxname(pc),a1
  41.     moveq    #36,d0
  42.     move.l    4.w,a6
  43.     jsr        OpenLibrary(a6)
  44.     lea        GfxBase(pc),a0
  45.     move.l    d0,(a0)
  46.     beq        fail1
  47.     
  48.     lea        dosname(pc),a1
  49.     moveq    #36,d0
  50.     jsr        OpenLibrary(a6)
  51.     move.l    d0,d2                ; d2 gets DosBase
  52.     beq        fail2
  53.     
  54.     lea        intuiname(pc),a1
  55.     moveq    #36,d0
  56.     jsr        OpenLibrary(a6)
  57.     move.l    d0,d3                ; d3 gets IntuitionBase
  58.     beq        fail3
  59.     
  60.     jsr        Forbid(a6)
  61.  
  62.     ; Install patch
  63.     move.l    d0,a1
  64.     lea        newObtainGIRPort(pc),a0
  65.     move.l    a0,d0
  66.     move.l    #ObtainGIRPort,a0
  67.     jsr        SetFunction(a6)
  68.     lea        oldObtainGIRPort(pc),a0
  69.     move.l    d0,(a0)
  70.     
  71.     ; Clear CPU caches to flush data/instruction cache incoherence
  72.     jsr        CacheClearU(a6)
  73.     
  74. loop:
  75.     jsr        Permit(a6)
  76.  
  77.     ; Wait for ctrl-C
  78.     move.l    #SIGBREAKF_CTRL_C,d0
  79.     jsr        Wait(a6)
  80.     
  81.     jsr        Forbid(a6)
  82.  
  83.     ; Attempt to remove the patch
  84.     move.l    d3,a1                ; a1 gets IntuitionBase
  85.     move.l    oldObtainGIRPort(pc),d0
  86.     move.l    #ObtainGIRPort,a0
  87.     jsr        SetFunction(a6)
  88.     lea        newObtainGIRPort(pc),a0
  89.     cmp.l    a0,d0
  90.     beq.s    ok
  91.  
  92.     ; Oops, someone has patched over, put it back
  93.     move.l    d3,a1                ; a1 gets IntuitionBase
  94.     move.l    #ObtainGIRPort,a0
  95.     jsr        SetFunction(a6)
  96.     
  97.     ; We can't quit, so notify user with a beep
  98.     exg        d3,a6                ; a6 gets IntutionBase
  99.     move.l    #0,a0
  100.     jsr        DisplayBeep(a6)        ; it's safe to call display beep inside Forbid()
  101.     exg        d3,a6                ; a6 gets ExecBase
  102.     
  103.     bra.s    loop
  104.     
  105. ok:
  106.     ; Clear CPU caches to flush data/instruction cache incoherence
  107.     jsr        CacheClearU(a6)
  108.     jsr        Permit(a6)
  109.  
  110.     exg        d2,a6                ; a6 gets DosBase
  111.     
  112.     ; Notify user of subsequent quit
  113.     lea        exitmsg(pc),a0
  114.     move.l    a0,d1
  115.     jsr     PutStr(a6)
  116.     
  117.     ; Wait a second to let other tasks exit from the patch code
  118.     ; We can't be absolutely sure but this should be enough of a safeguard
  119.     moveq    #50,d1
  120.     jsr        Delay(a6)
  121.  
  122.     exg        d2,a6                ; a6 gets ExecBase
  123.     
  124.     moveq    #0,d7
  125.  
  126.     ; Close libraries and exit    
  127.     move.l    d3,a1                ; a1 gets IntutionBase
  128.     jsr        CloseLibrary(a6)
  129.     
  130. fail3:
  131.     move.l    d2,a1                ; a1 gets DosBase
  132.     jsr        CloseLibrary(a6)
  133.     
  134. fail2:
  135.     move.l    GfxBase(pc),a1
  136.     jsr        CloseLibrary(a6)
  137.     
  138. fail1:
  139.     move.l    d7,d0
  140.     rts
  141.  
  142. newObtainGIRPort:
  143.     ; First we should check for valid input
  144.     move.l    a0,d0                ; effective compare
  145.  
  146.     ; We'll call ObtainGIPort anyway, even if the GadgetInfo is NULL..
  147.     beq.s    null2
  148.     
  149.     ; save some regs
  150.     movem.l    a0/a5/a6,-(sp)
  151.  
  152.     ; assume layer is valid (usually is)
  153.     ; try to lock it
  154.     move.l    GfxBase(pc),a6
  155.     move.l    ggi_Layer(a0),a5    ; only one access of layer ptr
  156.     move.l    a5,d0                ; effective compare, faster than cmpi
  157.     beq.s    null1                ; We'll do old stuff if layer is NULL
  158.     jsr        AttemptLockLayerRom(a6)
  159.     ext.l    d0                    ; effective compare, sets return value
  160.     beq.s    null3
  161.  
  162.     ; Got a lock, free it (layer already in a5, gfxbase in a6)
  163.     jsr        UnlockLayerRom(a6)
  164.     
  165. null1:
  166.     ; layer is null
  167.     movem.l    (sp)+,a0/a5/a6
  168.  
  169. null2:
  170.     ; call original function
  171.     move.l    oldObtainGIRPort(pc),a1
  172.     jmp        (a1)
  173.  
  174. null3:
  175.     ; Attempt to lock the layer failed, return NULL (set above)
  176.     movem.l    (sp)+,a0/a5/a6
  177.     rts
  178.  
  179. oldObtainGIRPort:
  180.     dc.l    0
  181.  
  182. GfxBase:
  183.     dc.l    0
  184.  
  185. dosname:
  186.     dc.b    "dos.library",0
  187.  
  188. intuiname:
  189.     dc.b    "intuition.library",0
  190.  
  191. gfxname:
  192.     dc.b    "graphics.library",0
  193.  
  194. exitmsg:
  195.     dc.b    "SafeGIRPort gone",10,0
  196.     dc.b    "$VER: SafeGIRPort 1.0 (30.1.95)",0
  197.  
  198.     END
  199.